package edu.ynu.se.xiecheng.achitectureclass.shiro;

import edu.ynu.se.xiecheng.achitectureclass.utils.JwtUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Slf4j
@Component
public class UserRealm extends AuthorizingRealm {

    @Autowired
    private JwtUtil jwtUtil;

    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof JwtToken;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken auth) throws AuthenticationException {
        log.debug("开始验证token");

        if (auth == null) {
            log.error("AuthenticationToken 为空");
            throw new AuthenticationException("token不能为空");
        }

        String token = (String) auth.getCredentials();
        if (token == null) {
            log.error("Token 为空");
            throw new AuthenticationException("token不能为空");
        }

        log.debug("验证token: {}", token);

        try {
            // 验证token是否有效
            if (!jwtUtil.verify(token)) {
                log.error("Token 验证失败");
                throw new AuthenticationException("无效的token");
            }

            // 验证token是否过期
            if (jwtUtil.isExpire(token)) {
                log.error("Token 已过期");
                throw new AuthenticationException("token已过期");
            }

            // 获取用户信息
            String username = jwtUtil.getUsername(token);
            if (username == null) {
                log.error("无法从token中获取用户名");
                throw new AuthenticationException("无效的token");
            }

            log.debug("Token验证成功, 用户名: {}", username);
            return new SimpleAuthenticationInfo(token, token, getName());

        } catch (Exception e) {
            log.error("Token验证过程发生异常", e);
            throw new AuthenticationException("token验证失败: " + e.getMessage());
        }
    }

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        log.debug("获取授权信息");
        return new SimpleAuthorizationInfo();
    }
}